import mqtt, { MqttClient as MqttClientType, IClientOptions } from "mqtt";

class MqttClient {
  private client: MqttClientType;
  private keepAliveInterval: NodeJS.Timeout | null = null;
  private heartbeatTopic: string = "$heartbeat";

  constructor(config: MqttClientConfig) {
    const {
      host,
      endpoint,
      clientId,
      username,
      password,
      keepalive,
      cleanSession,
      connectTimeout,
    } = config;

    // MQTT 连接选项
    const options: IClientOptions = {
      clientId,
      username,
      password,
      keepalive,
      clean: cleanSession,
      connectTimeout,
    };
    // will: {
    //   topic: this.heartbeatTopic,
    //   payload: "Client disconnected",
    //   qos: 0,
    // },

    // 连接到 MQTT 代理
    this.client = mqtt.connect(`${host}${endpoint}`, options);

    this.client.on("connect", () => {
      console.log("MQTT 客户端连接成功");
    });

    this.client.on("error", (err) => {
      console.error("MQTT 连接出错:", err);
    });

    this.client.on("message", (topic, message) => {
      console.log(
        `Received message '${message.toString()}' on topic '${topic}'`
      );
    });

    this.client.on("close", () => {
      console.log("MQTT 连接已关闭");
    });
  }

  /**
   * 订阅一个主题
   * @param topic 主题名称
   * @param callback 消息处理函数
   */

  // callback: (topic: string, message: Buffer) => void
  public subscribe(topic: string): void {
    this.client.subscribe(topic, (err) => {
      if (err) {
        console.error(`Failed to subscribe to ${topic}:`, err);
      } else {
        console.log(`Subscribed to ${topic}`);
        // this.client.on("message", callback);
      }
    });
  }

  /**
   * 发布消息
   * @param topic 主题名称
   * @param message 消息内容
   * @param qos 服务质量等级
   */
  public publish(topic: string, message: string, qos: number = 0): void {
    this.client.publish(topic, message, {}, (err) => {
      if (err) {
        console.error(`Failed to publish message to ${topic}:`, err);
      } else {
        console.log(`Message published to ${topic}`);
      }
    });
  }

  /**
   * 启动心跳机制
   * @param interval 心跳间隔（秒）
   */
  public startHeartbeat(interval: number = 60): void {
    if (this.keepAliveInterval !== null) {
      console.warn("Heartbeat already started.");
      return;
    }
    this.keepAliveInterval = setInterval(() => {
      if (this.client.connected) {
        this.publish(this.heartbeatTopic, "heartbeat");
      }
    }, interval * 1000);
  }

  /**
   * 停止心跳机制
   */
  public stopHeartbeat(): void {
    if (this.keepAliveInterval !== null) {
      clearInterval(this.keepAliveInterval);
      this.keepAliveInterval = null;
      console.log("Heartbeat stopped.");
    }
  }

  /**
   * 断开连接
   */
  public disconnect(): void {
    this.client.end(true, () => {
      console.log("Disconnected from MQTT broker.");
    });
  }
}
export interface MqttClientConfig {
  host: string;
  endpoint: string;
  clientId: string;
  username: string;
  password: string;
  keepalive: number;
  cleanSession: boolean;
  connectTimeout: number;
}
export default MqttClient;
